package net.qiqb.dao.mybatis.plus.event;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import net.qiqb.core.domain.event.DomainEventLog;
import net.qiqb.core.domain.event.DomainEventLogPersistence;
import net.qiqb.spring.ApplicationContextHolder;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;

public class DomainEventLogPersistenceImpl implements DomainEventLogPersistence {

    private DomainEventLogDao domainEventLogDao;

    public synchronized void init() {
        if (domainEventLogDao == null) {
            this.domainEventLogDao = ApplicationContextHolder.get().getBean(DomainEventLogDao.class);
        }
    }

    @Override
    public DomainEventLog getByEventId(String eventId, String serviceName, String listenerId) {
        init();
        final DomainEventLogPO domainEventLogPO = domainEventLogDao.getByEventIdAndServiceName(eventId, serviceName, listenerId);
        if (domainEventLogPO != null) {
            final DomainEventLog domainEventLog = new DomainEventLog();
            BeanUtil.copyProperties(domainEventLogPO, domainEventLogPO);
            return domainEventLog;
        }
        return null;
    }

    @Override
    public boolean insert(DomainEventLog domainEventLog) {
        init();
        DomainEventLogPO domainEventLogPO = DomainEventLogPO.builder()
                .eventId(domainEventLog.getEventId())
                .eventContent(domainEventLog.getEventContent())
                .processIp(domainEventLog.getProcessIp())
                .beginProcessTime(domainEventLog.getBeginProcessTime())
                .processResult(domainEventLog.getProcessResult())
                .processServiceName(domainEventLog.getProcessServiceName())
                .notes(domainEventLog.getNotes())
                .finishProcessTime(domainEventLog.getFinishProcessTime())
                .listenerId(domainEventLog.getListenerId())
                .build();
        final boolean b = domainEventLogDao.savePO(domainEventLogPO);
        if (b) {
            domainEventLog.setId(domainEventLogPO.getId());
        }
        return b;
    }

    @Override
    public boolean updateSuccessById(String id, LocalDateTime beginProcessTime) {
        init();
        final LocalDateTime finishTime = LocalDateTime.now();
        final long between = LocalDateTimeUtil.between(beginProcessTime, finishTime, ChronoUnit.MILLIS);

        return domainEventLogDao.updateResultById(id, finishTime, between, "success", null);
    }

    @Override
    public boolean updateFailById(String id, LocalDateTime beginProcessTime, String failMsg) {
        init();
        final LocalDateTime finishTime = LocalDateTime.now();
        final long between = LocalDateTimeUtil.between(beginProcessTime, finishTime, ChronoUnit.MILLIS);
        return domainEventLogDao.updateResultById(id, finishTime, between, "fail", failMsg);
    }
}
